
#include "avl_test.h"





void dump_arr(const int *a, const int *pcnt)
{
    for (int i = 0;i < pcnt[0]; ++i) {
        printf("%d ", a[i]);
    }
    printf("\n");
}
void dump_vec(const char *fstr, const std::vector<int> &v)
{
    printf("%s\n", fstr);
    for (auto it = v.begin(); it != v.end(); ++it) {
        if(it != v.begin()) {
            printf(" ,");
        }
        printf("%d", *it);
    }


    printf("\n");
}

void  test_format(std::vector<int> &val_seqs,std::vector<int> &op_seqs)
{
    avl_node *root = nullptr;
    
    int cnt = 0;

    std::string tstr{};

    avl_op_tp pre_op{AVL_NULL_OP};

    for (auto op : op_seqs) {

        if ( op == AVL_INSERT) {
            avl_insert( &root, val_seqs[cnt]);
            if ( pre_op != op) {
                tstr += "IN";
            }
            tstr += ' ';
            tstr += std::to_string( val_seqs[cnt]);
        }
        else if ( op == AVL_DEL) {
            avl_delete( &root, val_seqs[cnt]);
            if ( pre_op != op ) {
                tstr += "DL";
            }
            tstr += ' ';
            tstr += std::to_string( val_seqs[cnt]);
        }

        ++cnt;
        if ( cnt != op_seqs.size()) {
            tstr.push_back(',');
        }
        pre_op = static_cast<avl_op_tp>(op);
    }
    printf("%s\n", tstr.c_str());


    using avl_output_seq = std::vector<int>;
    avl_output_seq pre_seq{};
    auto in_seq = pre_seq;
    auto post_seq = pre_seq;

    avl_preorder_dump( root, pre_seq);
    avl_inorder_dump ( root, in_seq);
    avl_postorder_dump( root, post_seq);

    dump_vec( "preorder",pre_seq);
    dump_vec( "inorder" , in_seq);
    dump_vec( "postorder", post_seq);

    printf("\n\n");
}

void test_insert_noRotate()
{
    std::vector<int> val_seqs{2,1,3};
    std::vector<int> op_seqs{0,0,0}; 
    test_format( val_seqs, op_seqs);
}

void test_insert_lll() 
{

    std::vector<int> val_seqs{3,2,1};
    std::vector<int> op_seqs{0,0,0}; 
    test_format( val_seqs, op_seqs);

}

void test_insert_rrr() 
{
    std::vector<int> val_seqs{4,5,6};
    std::vector<int> op_seqs{0,0,0}; 
    test_format( val_seqs, op_seqs);
}
void test_insert_lr()
{
    std::vector<int> val_seqs{80,20,40};
    std::vector<int> op_seqs{0,0,0}; 
    test_format( val_seqs, op_seqs);
}

void test_insert_rl()
{

    std::vector<int> val_seqs { 100,300,121 };
    std::vector<int> op_seqs{0,0,0}; 
    test_format( val_seqs, op_seqs);
}

void test_insert_same()
{
    std::vector<int> val_seqs { 10,20,10 };
    std::vector<int> op_seqs{0,0,0}; 
    test_format( val_seqs, op_seqs);
}

void test_firstL_thenR()
{
    std::vector<int> val_seqs { 1,2,3,0,-1 };
    std::vector<int> op_seqs( val_seqs.size(), AVL_INSERT); 
    test_format( val_seqs, op_seqs);
}
void test_firstR_thenL()
{

    std::vector<int> val_seqs { 8, 2, 1, 9, 10};
    std::vector<int> op_seqs( val_seqs.size(), AVL_INSERT); 
    test_format( val_seqs, op_seqs);
}
void test_RotateR_twice()
{
    std::vector<int> val_seqs { 8, 2, 1, 5, 4};
    std::vector<int> op_seqs( val_seqs.size(), AVL_INSERT); 
    test_format( val_seqs, op_seqs);
}
void test_RotateL_twice()
{
    std::vector<int> val_seqs { 1, 2, 3, 4, 5};
    std::vector<int> op_seqs( val_seqs.size(), AVL_INSERT); 
    test_format( val_seqs, op_seqs);
}

void test_delete_root()
{   
    std::vector<int> val_seqs { 1, 2, 3, 2};
    std::vector<int> op_seqs( val_seqs.size() - 1, static_cast<int>(AVL_INSERT));
    op_seqs.push_back( static_cast<int>(AVL_DEL));
    test_format( val_seqs, op_seqs);
}
void test_delete_and_RotateL()
{
    std::vector<int> val_seqs { 1, 2, 5, 4, 7, 1};
    std::vector<int> op_seqs( val_seqs.size() - 1, static_cast<int>(AVL_INSERT));
    op_seqs.push_back( static_cast<int>(AVL_DEL));
    test_format( val_seqs, op_seqs);
}

void test_delete_and_RotateR()
{   
    std::vector<int> val_seqs { 7,9, 10, 5, 6, 10};
    std::vector<int> op_seqs( val_seqs.size() - 1, static_cast<int>(AVL_INSERT));
    op_seqs.push_back( static_cast<int>(AVL_DEL));
    test_format( val_seqs, op_seqs);


    std::vector<int> v2{ 33, 13, 53, 9, 21, 61, 8, 11, 13};
    std::vector<int> o2( v2.size() - 1, static_cast<int>(AVL_INSERT));
    o2.push_back( static_cast<int>(AVL_DEL));
    test_format( v2, o2);
}

void test_delete_and_RotateLR()
{
    std::vector<int> val_seqs { 70, 80, 90, 100, 90, 100};
    std::vector<int> op_seqs( val_seqs.size() - 1, static_cast<int>(AVL_INSERT));
    op_seqs.push_back( static_cast<int>(AVL_DEL));
    test_format( val_seqs, op_seqs);
}
void test_delete_and_RotateRL()
{
    std::vector<int> val_seqs { 27, 35, 42, 38, 27};
    std::vector<int> op_seqs( val_seqs.size() - 1, static_cast<int>(AVL_INSERT));
    op_seqs.push_back( static_cast<int>(AVL_DEL));
    test_format( val_seqs, op_seqs);    
}

void test_delete_and_adjust_twice()
{
    std::vector<int> val_seqs { 15, 9, 20, 7, 10, 17, 23, 8, 16, 18, 22, 24, 19, 10};
    std::vector<int> op_seqs( val_seqs.size() - 1, static_cast<int>(AVL_INSERT));
    op_seqs.push_back( static_cast<int>(AVL_DEL));
    test_format( val_seqs, op_seqs);    
}
void test_known_seqs()
{
    std::vector<int> val_seqs{ 30, 20, 40, 10, 25, 5, 15, 35, 50, 60 };
    std::vector<int> op_seqs( val_seqs.size() , static_cast<int>(AVL_INSERT));

    test_format( val_seqs, op_seqs);
}


bool AVLTestRunner::run_test_case(const avl_test_case& test_case) {
        // std::cout << "Running test: " << test_case.name << std::endl;
        // std::cout << "Description: " << test_case.description << std::endl;
        

        bool test_passed{true};
        avl_node* root = nullptr;
        bool all_operations_succeeded = true;
        
        int idx{};

        // 执行所有操作
        for (const auto& op : test_case.op) {
            bool success = true;


            for (int i = 0; i < op.cnt; ++i) {            
                auto input_v = test_case.input[idx];
                switch (op.tp) {
                    case AVL_FIND:
                        avl_find( &root, input_v);
                        idx++;
                        break;
                    case AVL_INSERT:
                        avl_insert( &root, input_v);
                        idx++;
                        break;
                    case AVL_DEL:
                        avl_delete( &root, input_v);
                        idx++;
                        break;
                    default:

                        break;
                }
            }
        }
        
        // 验证遍历结果

        std::vector<int> actual_inorder_seq{};
        avl_inorder_dump( root, actual_inorder_seq);

        bool is_order_same = ( actual_inorder_seq == test_case.expect_seq);


        if ( not is_order_same) {
            
            auto actual_sz = actual_inorder_seq.size();
            auto expect_sz = test_case.expect_seq.size();

            if ( actual_sz != expect_sz) {
                std::cout << "actual size: " << actual_sz << "\n";
                std::cout << "expect size: " << expect_sz << "\n";
            }
            
            decltype(actual_sz) first_not_eq_idx {expect_sz};
            for (int i = 0;i < actual_sz; ++i) {
                if (i >= expect_sz || actual_inorder_seq[i] != test_case.expect_seq[i]) {
                    first_not_eq_idx = i;
                    break;
                }
            }

            
            if ( first_not_eq_idx < actual_sz && first_not_eq_idx < expect_sz) {
                std::cout << "first not equal idx: " << first_not_eq_idx << "\n";
                std::cout << "expect: [" << test_case.expect_seq[first_not_eq_idx] << "], ";
                std::cout << "actual: (" << actual_inorder_seq[first_not_eq_idx] << ") !\n";
             }


            test_passed =  false;
        }


        // 输出结果
        if (false == avl_verify( root ) ) {
            std::cout << "height not correct!\n";
            test_passed = false;
        }

        avl_free_node( root );

        return test_passed;
}
    
void AVLTestRunner::run_test_suite(const avl_test_suite &test_suite) {
        std::cout << "Running test suite: " << test_suite.suite_name << std::endl;
        std::cout << "=========================================" << std::endl;
        
        int passed = 0;
        int total = test_suite.cases.size();

        std::vector<int> failed_case_idxs{};
        int idx{};
        
        for (const auto& test_case : test_suite.cases) {
            if (run_test_case(test_case)) {
                passed++;
            }
            else{
                failed_case_idxs.push_back(idx);
            }
            std::cout << std::endl;
            ++idx;
        }
        
        std::cout << "=========================================" << std::endl;
        std::cout << "Test suite results: " << passed << "/" << total << " tests passed" << std::endl;
        if ( !failed_case_idxs.empty()) {
            std::cout << "failed test idxs: ";
            for (auto idx: failed_case_idxs) {
                std::cout << " " << idx ;
            }
            std::cout << std::endl;
        }
}



    
    // 从文件加载数据
void AVLTestManager::load_data() {
        std::ifstream file(filename_);
        if (!file.good()) {
            // 文件不存在，创建基本结构
            data_ = nlohmann::json::object();
            data_["hello"] = "world";
            data_["tests"] = nlohmann::json::array();
        } else {
            try {
                data_ = nlohmann::json::parse(file);
            } catch (const nlohmann::json::parse_error& e) {
                throw std::runtime_error("Failed to parse JSON file: " + std::string(e.what()));
            }
        }
    }
    
    // 保存数据到文件
void AVLTestManager::save_data() {
    std::ofstream file(filename_);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file for writing: " + filename_);
    }
    file << std::setw(4) << data_ << std::endl;
}
        
    // 添加测试用例到指定套件
bool AVLTestManager::addTestCase(const std::string& suiteName, const avl_test_case& testCase) {
    auto& testsArray = data_["tests"];
    bool suiteFound = false;
    bool caseFound = false;
    
    for (auto& suite : testsArray) {
        if (suite["suite_name"] == suiteName) {
            suiteFound = true;
            auto& casesArray = suite["cases"];
            
            // 检查是否已存在相同的测试用例
            for (const auto& existingCase : casesArray) {
                auto existingCaseObj = existingCase.get<avl_test_case>();
                if (existingCaseObj.isEqual(testCase)) {
                    caseFound = true;
                    break;
                }
            }
            
            if (!caseFound) {
                casesArray.push_back(testCase);
                save_data();
                return true;
            }
            break;
        }
    }
    
    if (!suiteFound) {
        // 创建新套件
        avl_test_suite newSuite;
        newSuite.suite_name = suiteName;
        newSuite.cases.push_back(testCase);
        
        testsArray.push_back(newSuite);
        save_data();
        return true;
    }
    
    return false;
}
    
    // 删除整个测试套件
bool AVLTestManager::removeTestSuite(const std::string& suiteName) {
    auto& testsArray = data_["tests"];
    
    for (auto it = testsArray.begin(); it != testsArray.end(); ++it) {
        if ((*it)["suite_name"] == suiteName) {
            testsArray.erase(it);
            save_data();
            return true;
        }
    }
    
    return false;
}
    
    // 删除特定测试用例
bool AVLTestManager::removeTestCase(const std::string& suiteName, const avl_test_case& targetCase) {
    auto& testsArray = data_["tests"];
    
    for (auto& suite : testsArray) {
        if (suite["suite_name"] == suiteName) {
            auto& casesArray = suite["cases"];
            
            for (auto it = casesArray.begin(); it != casesArray.end(); ++it) {
                auto currentCase = it->get<avl_test_case>();
                if (currentCase.isEqual(targetCase)) {
                    casesArray.erase(it);
                    save_data();
                    return true;
                }
            }
            break;
        }
    }
    
    return false;
}
    
// 通过索引删除测试用例
bool AVLTestManager::removeTestCaseByIndex(const std::string& suiteName, size_t index) {
    auto& testsArray = data_["tests"];
    
    for (auto& suite : testsArray) {
        if (suite["suite_name"] == suiteName) {
            auto& casesArray = suite["cases"];
            
            if (index < casesArray.size()) {
                casesArray.erase(casesArray.begin() + index);
                save_data();
                return true;
            }
            break;
        }
    }
    
    return false;
}

// 获取所有测试套件
std::vector<avl_test_suite> AVLTestManager::getAllTestSuites() {
    return data_["tests"].get<std::vector<avl_test_suite>>();
}

